package cn.chiship.sdk.core.util;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.UnsupportedEncodingException;
import java.util.*;

/**
 * 中文转拼音工具类
 *
 * @author lijian
 */
public class ChineseCharToEn {

    private static final Logger LOGGER = LoggerFactory.getLogger(ChineseCharToEn.class);

    private static final int[] LI_SECPOSVALUE = {1601, 1637, 1833, 2078, 2274, 2302, 2433, 2594, 2787, 3106, 3212,
            3472, 3635, 3722, 3730, 3858, 4027, 4086, 4390, 4558, 4684, 4925, 5249, 5590};

    private static final String[] LC_FIRSTLETTER = {"a", "b", "c", "d", "e", "f", "g", "h", "j", "k", "l", "m", "n",
            "o", "p", "q", "r", "s", "t", "w", "x", "y", "z"};

    private static final Integer A = 1600;

    private static final Integer B = 5590;

    private static final Integer C = 23;

    private ChineseCharToEn() {

    }

    /**
     * 取得给定汉字的首字母,即声母
     *
     * @param chinese 给定的汉字
     * @return 结果 给定汉字的声母
     */
    public static String getFirstLetter(String chinese) {
        if (chinese == null || chinese.trim().length() == 0) {
            return "";
        }
        chinese = conversionStr(chinese, "GBK", "ISO8859-1");
        if (chinese.length() > 1) {
            int liSectorCode = chinese.charAt(0);
            int liPositionCode = chinese.charAt(1);
            liSectorCode = liSectorCode - 160;
            liPositionCode = liPositionCode - 160;
            int liSecPosCode = liSectorCode * 100 + liPositionCode;
            if (liSecPosCode > A && liSecPosCode < B) {
                for (int i = 0; i < C; i++) {
                    if (liSecPosCode >= LI_SECPOSVALUE[i] && liSecPosCode < LI_SECPOSVALUE[i + 1]) {
                        chinese = LC_FIRSTLETTER[i];
                        break;
                    }
                }
            } else // 非汉字字符,如图形符号或ASCII码
            {
                chinese = conversionStr(chinese, "ISO8859-1", "GBK");
                chinese = chinese.substring(0, 1);
            }
        }

        return chinese;
    }

    /**
     * 取得给定短语的各字首字母
     *
     * @param str
     * @return 结果
     */
    public static String getAllFirstLetters(String str) {
        StringBuilder convert = new StringBuilder();
        for (int j = 0; j < str.length(); j++) {
            char word = str.charAt(j);
            String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);
            if (pinyinArray != null) {
                convert.append(pinyinArray[0].charAt(0));
            } else {
                convert.append(word);
            }
        }
        return convert.toString();
    }
    private static String conversionStr(String str, String charsetName, String toCharsetName) {
        try {
            str = new String(str.getBytes(charsetName), toCharsetName);

        } catch (UnsupportedEncodingException ex) {
            LOGGER.error("字符串编码转换异常", ex);
        }

        return str;
    }

    /**
     * 返回汉语拼音的全拼
     *
     * @param text
     * @return 结果
     */
    public static String getPinYinAll(String text) {
        List<String> result = new ArrayList<>();
        result.add("");
        char[] t1 = null;
        t1 = text.toCharArray();

        // 设置汉字拼音的输出格式
        HanyuPinyinOutputFormat hf = new HanyuPinyinOutputFormat();
        // 设置输出类型为小写
        hf.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        // 设置音标类型为无音标
        hf.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        // 设置 吕中u转换为v
        hf.setVCharType(HanyuPinyinVCharType.WITH_V);

        for (char c : t1) {
            // 判断是否是汉字
            if (Character.toString(c).matches("[\\u4E00-\\u9FA5]+")) {
                try {
                    String[] t2 = PinyinHelper.toHanyuPinyinStringArray(c, hf);
                    // 去掉 多音词中 拼音相同 声调不同的重复拼音
                    Set<String> set = new HashSet<>();
                    set.addAll(Arrays.asList(t2));
                    t2 = set.toArray(new String[0]);
                    if (t2 != null && t2.length > 1) {
                        List<String> temp = new ArrayList<>();
                        temp.addAll(result);
                    } else {
                        int n = result.size();
                        for (int i = 0; i < n; i++) {
                            String s = result.get(i);
                            result.remove(i);
                            result.add(i, s + t2[0]);
                        }
                    }
                } catch (BadHanyuPinyinOutputFormatCombination e) {
                    LOGGER.error("发生异常", e);
                }
            } else {
                int n = result.size();
                for (int i = 0; i < n; i++) {
                    String s = result.get(i);
                    result.remove(i);
                    result.add(i, s + String.valueOf(c));
                }
            }
        }
        if (result.isEmpty()) {
            return "";
        } else {
            return result.get(0);
        }
    }

    public static boolean containsAny(String str, String searchChars) {
        return str.length() != str.replace(searchChars, "").length();
    }

}
